package edu.cornell.cubooks.validator;

import java.util.regex.Pattern;

import net.tanesha.recaptcha.ReCaptchaResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;

import edu.cornell.cubooks.dao.UserDao;
import edu.cornell.cubooks.domain.User;
import edu.cornell.cubooks.utils.CurrentUser;
import edu.cornell.cubooks.utils.Santizer;

public class UserValidator {
	
	private UserDao userDao;
	
    private static final String EMAIL_REGEXP =
        "^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$";
    
    private static final String NAME_PATTERN = "[A-Za-z0-9]*";
    
    private static final int MIN_PASSWD_LENGTH = 6;

    private static final Pattern emailPattern = Pattern.compile(EMAIL_REGEXP, Pattern.CASE_INSENSITIVE);
	
    private static final Pattern namePattern = Pattern.compile(NAME_PATTERN, Pattern.CASE_INSENSITIVE);
	
    
    @Autowired
	public UserValidator(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public void validateForgotPassword(User user, Errors errors, ReCaptchaResponse reCaptchaResponse) {
		
		if (!reCaptchaResponse.isValid()) {
			errors.rejectValue("captcha", "user.captcha.notvalid");
	    }
		
		if(!StringUtils.hasLength(user.getUsername())){
			errors.rejectValue("username", "user.username.required");
		}
		else if (!userDao.userNameExists(user.getUsername())) {
			errors.rejectValue("username", "user.username.doesntexist");
		}
	}
	
	public boolean validateResetPassword(User user, String token) {
		if (user == null) {
			return false;
		}
		
		if (!userDao.checkToken(user, token)) {
			return false;
		}
		return true;
	}
	
	public void validateNewPassword(User user, Errors errors){
		user = santize(user);
		
		if(!user.getPassword().equals(user.getCpassword())){
			errors.rejectValue("password", "user.password.dontmatch");
			errors.rejectValue("cpassword", "user.password.dontmatch");	
		}
		
		if(!StringUtils.hasLength(user.getPassword()) || user.getPassword().length() < MIN_PASSWD_LENGTH){
			errors.rejectValue("password", "user.password.required");
		}
		
		if(!StringUtils.hasLength(user.getCpassword()) || user.getCpassword().length() < MIN_PASSWD_LENGTH){
			errors.rejectValue("cpassword", "user.password.required");
		}
		
	}
	
	public void validateRequestSeller(User user, Errors errors){
		user = santize(user);
		
		if(user.getRequestSeller() == null || user.getRequestSeller() == 0){
			errors.rejectValue("requestSeller", "user.requestSeller.required");
		}
	}
	
	public void validateEditAccount(User user, Errors errors) {

		user = santize(user);
		
		if(!StringUtils.hasLength(user.getFirstName().trim())){
			errors.rejectValue("firstName", "user.firstName.required");
		}
		
		if(!StringUtils.hasLength(user.getLastName().trim())){
			errors.rejectValue("lastName", "user.lastName.required");
		}
		
		if(user.getAge() == null){
			errors.rejectValue("age", "user.age.required");
		}

		if(user.getAge() != null && user.getAge() < 18){
			errors.rejectValue("age", "user.age.min18");
		}
		
		if(!StringUtils.hasLength(user.getUsername())){
			errors.rejectValue("username", "user.username.required");
		}
		
		if(!emailPattern.matcher(user.getEmailAddress()).matches() && StringUtils.hasLength(user.getEmailAddress())) {
            errors.rejectValue("emailAddress", "user.invalid.email");
        }
		
		if(userDao.emailExistsForOtherUser(user.getEmailAddress().trim(), user.getId())){
			errors.rejectValue("emailAddress", "user.emailAddressforOtherUser.exists", new Object[]{user.getEmailAddress()}, "");
		}
		
		if(userDao.userNameExistsForOtherUser(user.getUsername().trim(), user.getId())){
			errors.rejectValue("username", "user.username.exists", new Object[]{user.getUsername()}, "");
		}
		
		if(CurrentUser.getUser().equals(user)) {
			if(!user.getPassword().equals(user.getCpassword())){
				errors.rejectValue("password", "user.password.dontmatch");
				errors.rejectValue("cpassword", "user.password.dontmatch");	
			}
			
			if(!StringUtils.hasLength(user.getPassword()) || user.getPassword().length() < MIN_PASSWD_LENGTH){
				errors.rejectValue("password", "user.password.required");
			}
			
			if(!StringUtils.hasLength(user.getCpassword()) || user.getCpassword().length() < MIN_PASSWD_LENGTH){
				errors.rejectValue("cpassword", "user.password.required");
			}
		}
		
	}
	
	public void validate(User user, Errors errors, ReCaptchaResponse reCaptchaResponse) {
		user = santize(user);
		
		if (!reCaptchaResponse.isValid()) {
			errors.rejectValue("captcha", "user.captcha.notvalid");
	    }

		if(userDao.userNameExists(user.getUsername().trim())){
			errors.rejectValue("username", "user.username.exists", new Object[]{user.getUsername()}, "");
		}
		
		if(userDao.emailExists(user.getEmailAddress().trim())){
			errors.rejectValue("emailAddress", "user.emailAddress.exists", new Object[]{user.getEmailAddress()}, "");
		}
		
		if(!StringUtils.hasLength(user.getUsername())){
			errors.rejectValue("username", "user.username.required");
		}
		
		if(!user.getPassword().equals(user.getCpassword())){
			errors.rejectValue("password", "user.password.dontmatch");
			errors.rejectValue("cpassword", "user.password.dontmatch");	
		}
		
		if(!StringUtils.hasLength(user.getPassword()) || user.getPassword().length() < MIN_PASSWD_LENGTH){
			errors.rejectValue("password", "user.password.required");
		}
		
		if(!StringUtils.hasLength(user.getCpassword()) || user.getCpassword().length() < MIN_PASSWD_LENGTH){
			errors.rejectValue("cpassword", "user.password.required");
		}
		
		if(!emailPattern.matcher(user.getEmailAddress()).matches() && StringUtils.hasLength(user.getEmailAddress())) {
            errors.rejectValue("emailAddress", "user.invalid.email");
        }
		
		if(!emailPattern.matcher(user.getCemailAddress()).matches() && StringUtils.hasLength(user.getCemailAddress())) {
            errors.rejectValue("cemailAddress", "user.invalid.email");
        }
		
		if(!namePattern.matcher(user.getUsername()).matches()) {
            errors.rejectValue("username", "user.invalid.namepattern");
        }
		
		if(!namePattern.matcher(user.getFirstName()).matches()) {
            errors.rejectValue("firstName", "user.invalid.namepattern");
        }
		
		if(!namePattern.matcher(user.getLastName()).matches()) {
            errors.rejectValue("lastName", "user.invalid.namepattern");
        }
		
		if(!user.getEmailAddress().trim().equals(user.getCemailAddress().trim())){
			errors.rejectValue("emailAddress", "user.email.dontmatch");
			errors.rejectValue("cemailAddress", "user.email.dontmatch");
		}
		
		if(!StringUtils.hasLength(user.getEmailAddress().trim())){
			errors.rejectValue("emailAddress", "user.email.required");
		}
		
		if(!StringUtils.hasLength(user.getCemailAddress().trim())){
			errors.rejectValue("cemailAddress", "user.email.required");
		}
		
		if(!StringUtils.hasLength(user.getFirstName().trim())){
			errors.rejectValue("firstName", "user.firstName.required");
		}
		
		if(!StringUtils.hasLength(user.getLastName().trim())){
			errors.rejectValue("lastName", "user.lastName.required");
		}
		
		if(user.getAge() == null){
			errors.rejectValue("age", "user.age.required");
		}

		if(user.getAge() != null && user.getAge() < 18){
			errors.rejectValue("age", "user.age.min18");
		}
	}
	
	private User santize(User user) {
		user.setFirstName(Santizer.santize(user.getFirstName()));
		user.setLastName(Santizer.santize(user.getLastName()));
		user.setEmailAddress(Santizer.santize(user.getEmailAddress()));
		user.setUsername((Santizer.santize(user.getUsername())));
		return user;
	}
}
